/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.rpc.table;

import com.alibaba.fastjson2.JSONArray;
import com.google.common.collect.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.constants.ConstantVars;
import com.je.common.base.constants.table.TableType;
import com.je.common.base.db.JEDatabase;
import com.je.common.base.entity.extjs.DbModel;
import com.je.common.base.exception.APIWarnException;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.table.BuildingSqlFactory;
import com.je.common.base.table.service.PCDataService;
import com.je.common.base.util.DataBaseUtils;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.ibatis.extension.enums.DbType;
import com.je.ibatis.extension.metadata.IdType;
import com.je.table.vo.TableDataView;
import org.apache.servicecomb.provider.pojo.RpcReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class MetaTableRpcServiceImpl implements MetaTableRpcService {

    private static final Logger logger = LoggerFactory.getLogger(MetaTableRpcServiceImpl.class);

    @RpcReference(microserviceName = "meta", schemaId = "metaTableRpcService")
    private MetaTableRpcService metaTableRpcService;
    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private PCDataService pcDataService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private BeanService beanService;

    @Autowired
    private ChangePrimaryKeyRpcService changePrimaryKeyRpcService;

    @Override
    public boolean createTable(String resourceTableId) {
        boolean success = true;
        String result = checkTableForApply(resourceTableId);
        if (StringUtil.isNotEmpty(result)) {
            throw new PlatformException(result, PlatformExceptionEnum.UNKOWN_ERROR);
        }
        List<String> arraySql = generateCreateDDL(resourceTableId);
        for (String sql : arraySql) {
            if (StringUtil.isNotEmpty(sql)) {
                metaService.executeSql(sql);
            }
        }
        afterTableCreated(resourceTableId);
        return success;
    }

    @Override
    public DynaBean changePrimaryKeyPolicy(String resourceId, String tableCode, String type, String incrementerName, String generatorSql) {
       /* if (metaService.getDbType() != DbType.MYSQL && IdType.getIdType(type) == IdType.AUTO) {
            throw new PlatformException("设置主键策略异常!只支持mysql自增！", PlatformExceptionEnum.JE_CORE_TABLE_ERROR);
        }*/
        DynaBean table = metaResourceService.selectOneByNativeQuery("JE_CORE_RESOURCETABLE",NativeQuery.build().eq("RESOURCETABLE_TABLECODE",tableCode));
        String RESOURCETABLE_KEY_GENERATOR_TYPE = table.getStr("RESOURCETABLE_KEY_GENERATOR_TYPE");
        if (IdType.getIdType(type) == IdType.AUTO) {
            try {
                String pkCode = beanService.getPKeyFieldNamesByTableCode(tableCode);
                metaService.executeSql(BuildingSqlFactory.build().getDDL4SetPrimaryStrategy(tableCode,pkCode));
                List<DynaBean> list = metaService.select(tableCode,ConditionsWrapper.builder().orderByDesc(pkCode));
                if(list.size()==0){
                    metaService.executeSql(BuildingSqlFactory.build().getDDL4SetStep(tableCode,pkCode,1,1));
                }else{
                   Integer pkValue = list.get(0).getInt(pkCode);
                   metaService.executeSql(BuildingSqlFactory.build().getDDL4SetStep(tableCode,pkCode,pkValue+1,1));
                }
            } catch (Exception e) {
                throw new PlatformException("设置主键策略异常!请检查现存数据是否符合自增！", PlatformExceptionEnum.JE_CORE_TABLE_ERROR);
            }
        }
        if (IdType.getIdType(type) == IdType.AUTO_INCREMENTER || IdType.getIdType(type) == IdType.SQL) {
            deleteIncrement(RESOURCETABLE_KEY_GENERATOR_TYPE,tableCode);
            try {
                String pkCode = beanService.getPKeyFieldNamesByTableCode(tableCode);
                metaService.executeSql(BuildingSqlFactory.build().getDDL4ModifyColumnType(tableCode,pkCode,"BIGINT",false));
            } catch (Exception e) {
                throw new PlatformException("设置主键策略异常!请检查现存数据是否符合序列！", PlatformExceptionEnum.JE_CORE_TABLE_ERROR);
            }
        }
        if (IdType.getIdType(type) == IdType.UUID) {
            deleteIncrement(RESOURCETABLE_KEY_GENERATOR_TYPE,tableCode);
            String pkCode = beanService.getPKeyFieldNamesByTableCode(tableCode);
            metaService.executeSql(BuildingSqlFactory.build().getDDL4ModifyColumnType(tableCode,pkCode,"VARCHAR(50)",false));
        }
        //去除主键约束
        if (IdType.getIdType(type) == IdType.NONE) {
            metaService.executeSql(String.format("ALTER TABLE " + tableCode + " DROP PRIMARY KEY;"));
        }
        DynaBean dynaBean = metaTableRpcService.changePrimaryKeyPolicy(resourceId, tableCode, type, incrementerName, generatorSql);
        metaService.clearMyBatisTableCache(tableCode);
        return dynaBean;
    }

    public void deleteIncrement(String oldType,String tableCode){
        if(IdType.getIdType(oldType) == IdType.AUTO){
            //如果由AUTO变为其他策略，达梦需先删除自增，才能改变主键字段类型
            try{
                String ddl = BuildingSqlFactory.build().getDDL4DeleteIncrement(tableCode);
                if(StringUtil.isNotEmpty(ddl)){
                    metaService.executeSql(ddl);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<String> clearTableCache(String tableCode) {
        return metaTableRpcService.clearTableCache(tableCode);
    }

    @Override
    public List<String> generateChangeTablePrimaryKeyDDL(String tableCode, String oldPk, String newPK) {
        return metaTableRpcService.generateChangeTablePrimaryKeyDDL(tableCode, oldPk, newPK);
    }

    @Override
    public List<DynaBean> findTableNames(List<String> idList) {
        return metaTableRpcService.findTableNames(idList);
    }

    @Override
    public List<String> generateCreateDDL(String resourceTableId) {
        return metaTableRpcService.generateCreateDDL(resourceTableId);
    }

    @Override
    public DynaBean afterTableCreated(String resourceTableId) {
        DynaBean dynaBean = metaTableRpcService.afterTableCreated(resourceTableId);
        if (TableType.TREETABLE.equals(dynaBean.get("RESOURCETABLE_TYPE")) && !"1".equals(dynaBean.get("RESOURCETABLE_MOREROOT"))) {
            dynaBean.table(dynaBean.getStr("RESOURCETABLE_TABLECODE"));
            metaService.insert(dynaBean);
        }
        return null;
    }

    @Override
    public List<String> generateUpdateDDL(String resourceTableId, List<DbModel> dbModels) {
        DynaBean resourceTable = metaResourceService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceTableId);
        Boolean jeCore = ("1".equals(resourceTable.getStr("SY_JECORE")));

        List<DynaBean> columns = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLECOLUMN",
                NativeQuery.build().applyWithParams("TABLECOLUMN_RESOURCETABLE_ID={0} ORDER BY TABLECOLUMN_CLASSIFY ASC,SY_ORDERINDEX ASC",
                        resourceTable.getStr("JE_CORE_RESOURCETABLE_ID")));

        List<DynaBean> keys = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLEKEY",
                NativeQuery.build().eq("TABLEKEY_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID")));

        List<DynaBean> indexs = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLEINDEX",
                NativeQuery.build().eq("TABLEINDEX_RESOURCETABLE_ID", resourceTable.getStr("JE_CORE_RESOURCETABLE_ID")));

        resourceTable.set(BeanService.KEY_TABLE_COLUMNS, columns);
        resourceTable.set(BeanService.KEY_TABLE_KEYS, keys);
        resourceTable.set(BeanService.KEY_TABLE_INDEXS, indexs);
        //获取clob字段
        List<String> arraySql = BuildingSqlFactory.build().getDDL4UpdateTable(resourceTable, dbModels);
        return arraySql;
    }

    @Override
    public void afterTableUpdated(String resourceTableId) {
        metaTableRpcService.afterTableUpdated(resourceTableId);
    }

    @Override
    public List<String> generateRemoveDDL(String ids) {
        return metaTableRpcService.generateRemoveDDL(ids);
    }


    @Override
    public DynaBean impTable(DynaBean table) {
        table = metaTableRpcService.beforeImportBuildDynabeanInfo(table);
        DataBaseUtils.buildDynabeanTableInfo(table);
        String tableCode = table.getStr("RESOURCETABLE_TABLECODE");
        String RESOURCETABLE_TYPE = table.getStr("RESOURCETABLE_TYPE");
        if ("VIEW".equals(RESOURCETABLE_TYPE)) {
            List<Map<String, Object>> lists = metaService.selectSql("SHOW CREATE VIEW " + tableCode + "");
            return metaTableRpcService.afterImportMetaInfo(table, lists);
        }
        return metaTableRpcService.afterImportMetaInfo(table, null);
    }

    @Override
    public DynaBean syncTable(DynaBean table, List<DbModel> dbModels, boolean isDdl) {
        DynaBean tableInfo = new DynaBean("JE_CORE_RESOURCETABLE", false);
        tableInfo.set("RESOURCETABLE_TABLECODE", table.getStr("RESOURCETABLE_TABLECODE"));
        tableInfo.set("RESOURCETABLE_ISCREATE", "1");
        DataBaseUtils.buildDynabeanTableInfo(tableInfo);
        List<DynaBean> columnsList = (List<DynaBean>) tableInfo.get(BeanService.KEY_TABLE_COLUMNS);
        Map<String, String> columnMap = new HashMap<>();
        for (DynaBean columnItem : columnsList) {
            String tablecolumnName = columnItem.getStr("TABLECOLUMN_NAME");
            String tablecolumnCode = columnItem.getStr("TABLECOLUMN_CODE");
            columnMap.put(tablecolumnCode, tablecolumnName);
        }

        String tableCode = table.getStr("RESOURCETABLE_TABLECODE");
        List<DynaBean> columns = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLECOLUMN",
                NativeQuery.build().eq("TABLECOLUMN_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID")));
        //找到需要删除的列
        for (DynaBean column : columns) {
            String columnCode = column.getStr("TABLECOLUMN_CODE", "");
            boolean have = false;
            for (DbModel dbModel : dbModels) {
                if (columnCode.equals(dbModel.getCode())) {
                    have = true;
                    break;
                }
            }
            //不包含此列，则删除
            if (!have) {
                metaResourceService.deleteByTableCodeAndNativeQuery("JE_CORE_TABLECOLUMN", NativeQuery.build()
                        .eq("JE_CORE_TABLECOLUMN_ID", column.getStr("JE_CORE_TABLECOLUMN_ID")));
            }
        }

        //设置主键
        String pkCode = table.getStr("RESOURCETABLE_PKCODE");
        if (StringUtil.isEmpty(pkCode)) {
            List<DynaBean> keys = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLEKEY",
                    NativeQuery.build().eq("TABLEKEY_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID")));
            for (DynaBean key : keys) {
                if ("Primary".equals(key.getStr("TABLEKEY_TYPE"))) {
                    pkCode = key.getStr("TABLEKEY_COLUMNCODE");
                }
            }
            if (StringUtil.isNotEmpty(pkCode)) {
                table.set("RESOURCETABLE_PKCODE", pkCode);
                metaResourceService.updateBean(table);
            }
        }

        //增加的字段集合
        List<DynaBean> addedColumnList = null;
        for (DbModel dbModel : dbModels) {
            boolean have = false;
            addedColumnList = Lists.newArrayList();

            for (DynaBean column : columns) {
                if (StringUtil.isEmpty(column.getTableCode())) {
                    column.setStr(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLECOLUMN");
                }
                String columnCode = column.getStr("TABLECOLUMN_CODE", "");
                if (columnCode.equals(dbModel.getCode())) {
                    have = true;
                    boolean update = false;
                    if (!column.getStr("TABLECOLUMN_TYPE", "").equals(dbModel.getType())) {
                        update = true;
                        column.set("TABLECOLUMN_TYPE", dbModel.getType());
                    }
                    if (!column.getStr("TABLECOLUMN_LENGTH", "").equals(dbModel.getLength())) {
                        column.set("TABLECOLUMN_LENGTH", dbModel.getLength());
                        update = true;
                    }
                    if (!column.getStr("TABLECOLUMN_ISNULL", "").equals((dbModel.isNull() ? "1" : "0"))) {
                        column.set("TABLECOLUMN_ISNULL", dbModel.isNull() ? "1" : "0");
                        update = true;
                    }
                    if ("0".equals(column.getStr("TABLECOLUMN_ISCREATE"))) {
                        column.set("TABLECOLUMN_ISCREATE", "1");
                        update = true;
                    }
                    //2022.5.9，同步表结构时，若主键有变化，此代码会造成两个主键
                    /*if (column.getStr("TABLECOLUMN_CODE", "").equals(table.getStr("RESOURCETABLE_PKCODE"))) {
                        column.set("TABLECOLUMN_TYPE", "ID");
                        update = true;
                    }*/
                    if (columnMap.containsKey(columnCode)) {
                        String columnName = columnMap.get(columnCode);
                        if (StringUtil.isNotEmpty(columnName)) {
                            column.set("TABLECOLUMN_NAME", columnName);
                        } else if (StringUtil.isEmpty(column.getStr("TABLECOLUMN_NAME"))) {
                            column.set("TABLECOLUMN_NAME", column.getStr("TABLECOLUMN_CODE"));
                        }
                        update = true;
                    }
                    if (update) {
                        metaResourceService.updateBean(column);
                    }
                    continue;
                }
            }

            //现有元数据中没有此列，则把此列添加到元数据列表中
            if (!have) {
                DynaBean column = new DynaBean("JE_CORE_TABLECOLUMN", false);
                column.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLECOLUMN_ID");
                column.set("TABLECOLUMN_CODE", dbModel.getCode());
                column.set("TABLECOLUMN_OLDCODE", dbModel.getCode());
                if (columnMap.containsKey(dbModel.getCode())) {
                    column.set("TABLECOLUMN_NAME", columnMap.get(dbModel.getCode()));
                } else {
                    column.set("TABLECOLUMN_NAME", dbModel.getCode());
                }
                column.set("TABLECOLUMN_ISCREATE", "1");
                column.set("TABLECOLUMN_UNIQUE", "0");
                column.set("TABLECOLUMN_TREETYPE", "NORMAL");
                column.set("TABLECOLUMN_TABLECODE", tableCode);
                column.set("TABLECOLUMN_CLASSIFY", "PRO");
                column.set("SY_STATUS", "1");
                column.set("SY_ORDERINDEX", columns.size() + 1);
                column.set("TABLECOLUMN_ISNULL", dbModel.isNull() ? "1" : "0");
                column.set("TABLECOLUMN_TYPE", dbModel.getType());
                column.set("TABLECOLUMN_LENGTH", dbModel.getLength());
                column.set("TABLECOLUMN_TABLECODE", table.getStr("RESOURCETABLE_TABLECODE"));
                column.set("TABLECOLUMN_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                commonService.buildModelCreateInfo(column);
                if (column.getStr("TABLECOLUMN_CODE", "").equals(table.getStr("RESOURCETABLE_PKCODE"))) {
                    column.set("TABLECOLUMN_TYPE", "ID");
                }
                metaResourceService.insert(column);
                columns.add(column);
                addedColumnList.add(column);
            }
        }
        //同步表格键
        syncTableFormKey(table, tableInfo);
        //同步表格索引
        syncTableTableIndex(table, tableInfo);
        return table;
    }

    private void syncTableFormKey(DynaBean table, DynaBean tableInfo) {
        List<DynaBean> keys = (List<DynaBean>) tableInfo.get(BeanService.KEY_TABLE_KEYS);
        List<DynaBean> metaKeys = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLEKEY", NativeQuery.build().
                eq("TABLEKEY_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"))
                .ne("TABLEKEY_TYPE", "Unique"));
        for (DynaBean metaKey : metaKeys) {
            if (metaKey.getStr("TABLEKEY_TYPE").equals("Primary")) {
                continue;
            }
            String metaKeyCode = metaKey.getStr("TABLEKEY_CODE");
            Boolean exist = false;
            for (DynaBean key : keys) {
                String keyCode = key.getStr("TABLEKEY_CODE");
                if (metaKeyCode.equals(keyCode)) {
                    exist = true;
                    break;
                }
            }
            //元数据存在，数据库不存在，删除元数据
            if (!exist) {
                metaResourceService.deleteByTableCodeAndNativeQuery("JE_CORE_TABLEKEY", NativeQuery.build().eq(metaKey.getPkCode(), metaKey.getPkValue()));
            }
        }
        DynaBean metaInfo = new DynaBean();
        for (DynaBean key : keys) {
            if (key.get("TABLEKEY_TYPE").equals("Primary")) {
                continue;
            }
            String metaKeyCode = key.getStr("TABLEKEY_CODE");
            Boolean exist = false;
            for (DynaBean metaKey : metaKeys) {
                String keyCode = metaKey.getStr("TABLEKEY_CODE");
                if (metaKeyCode.equals(keyCode)) {
                    metaInfo = metaKey;
                    exist = true;
                    break;
                }
            }
            //数据库存在，元数据不存在，添加元数据
            if (!exist) {
                DynaBean dynaBean = new DynaBean("JE_CORE_TABLEKEY", false);
                dynaBean.setValues(key.getValues());
                dynaBean.setStr(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLEKEY");
                dynaBean.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLEKEY_ID");
                commonService.buildModelCreateInfo(dynaBean);
                dynaBean.setStr("TABLEKEY_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                dynaBean.setStr("TABLEKEY_CLASSIFY", "PRO");
                dynaBean.set("SY_ORDERINDEX", "0");
                metaResourceService.insert(dynaBean);
            } else {
                DynaBean dynaBean = new DynaBean("JE_CORE_TABLEKEY", false);
                dynaBean.setValues(key.getValues());
                dynaBean.setStr(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLEKEY");
                dynaBean.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLEKEY_ID");
                commonService.buildModelCreateInfo(dynaBean);
                dynaBean.setStr("TABLEKEY_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                dynaBean.setStr(dynaBean.getPkCode(), metaInfo.getPkValue());
                dynaBean.setStr("TABLEINDEX_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                dynaBean.set("SY_ORDERINDEX", metaInfo.getStr("SY_ORDERINDEX"));
                dynaBean.setStr("TABLEKEY_CLASSIFY", metaInfo.getStr("TABLEKEY_CLASSIFY"));
                metaResourceService.updateBean(dynaBean);
            }
        }


    }

    private void syncTableTableIndex(DynaBean table, DynaBean tableInfo) {
        List<DynaBean> indexs = (List<DynaBean>) tableInfo.get(BeanService.KEY_TABLE_INDEXS);
        List<DynaBean> metaIndexs = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_TABLEINDEX", NativeQuery.build().
                eq("TABLEINDEX_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID")));
        for (DynaBean metaIndex : metaIndexs) {
            String metaKeyCode = metaIndex.getStr("TABLEINDEX_NAME");
            Boolean exist = false;
            for (DynaBean index : indexs) {
                String keyCode = index.getStr("TABLEINDEX_NAME");
                if (metaKeyCode.equals(keyCode)) {
                    exist = true;
                    break;
                }
            }
            //元数据存在，数据库不存在，删除元数据
            if (!exist) {
                metaResourceService.deleteByTableCodeAndNativeQuery("JE_CORE_TABLEINDEX", NativeQuery.build().eq(metaIndex.getPkCode(), metaIndex.getPkValue()));
            }
        }

        for (DynaBean index : indexs) {
            if (index.getStr("TABLEINDEX_FIELDNAME").equals("主键ID")) {
                continue;
            }
            String indexCode = index.getStr("TABLEINDEX_NAME");
            Boolean exist = false;
            DynaBean metaInfo = new DynaBean();
            for (DynaBean metaIndex : metaIndexs) {
                String keyCode = metaIndex.getStr("TABLEINDEX_NAME");
                if (indexCode.equals(keyCode)) {
                    metaInfo = metaIndex;
                    exist = true;
                    break;
                }
            }
            //数据库存在，元数据不存在，添加元数据
            if (!exist) {
                DynaBean dynaBean = new DynaBean("JE_CORE_TABLEINDEX", false);
                dynaBean.setValues(index.getValues());
                dynaBean.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLEINDEX_ID");
                dynaBean.setStr(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLEINDEX");
                commonService.buildModelCreateInfo(dynaBean);
                dynaBean.setStr("TABLEINDEX_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                dynaBean.set("SY_ORDERINDEX", 0);
                metaResourceService.insert(dynaBean);
            } else {
                DynaBean dynaBean = new DynaBean("JE_CORE_TABLEINDEX", false);
                dynaBean.setValues(index.getValues());
                dynaBean.set(BeanService.KEY_PK_CODE, "JE_CORE_TABLEINDEX_ID");
                dynaBean.setStr(BeanService.KEY_TABLE_CODE, "JE_CORE_TABLEINDEX");
                commonService.buildModelModifyInfo(dynaBean);
                dynaBean.setStr(dynaBean.getPkCode(), metaInfo.getPkValue());
                dynaBean.setStr("TABLEINDEX_RESOURCETABLE_ID", table.getStr("JE_CORE_RESOURCETABLE_ID"));
                dynaBean.set("SY_ORDERINDEX", metaInfo.getStr("SY_ORDERINDEX"));
                metaResourceService.updateBean(dynaBean);
            }
        }

    }


    @Override
    public boolean updateTable(String resourceTableId, Boolean isFuncs) {
        boolean success = true;
        String result = checkTableForApply(resourceTableId);
        if (StringUtil.isNotEmpty(result)) {
            throw new PlatformException(result, PlatformExceptionEnum.UNKOWN_ERROR);
        }
        DynaBean resourceTable = metaResourceService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceTableId);
        List<DbModel> dbModels = pcDataService.loadTableColumnBySql(resourceTable.getStr("RESOURCETABLE_TABLECODE"));
        List<String> arraySql = generateUpdateDDL(resourceTableId, dbModels);
//            todo 神通数据-如果存在SY_PARENT外键，就不对此外键进行操作 huxaunhua
        if (JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SHENTONG)
                && metaService.countBySql("select count(*) from user_cons_columns where table_name='" + resourceTable.get("RESOURCETABLE_TABLECODE") + "' and column_name='SY_PARENT'") > 0) {
            arraySql.removeIf(s -> s.contains("foreign key (SY_PARENT)"));
        }
        for (String sql : arraySql) {
            sql = sql.replaceAll("\n", "");
            if (StringUtil.isNotEmpty(sql)) {
                metaService.executeSql(sql);
            }
        }
        afterTableUpdated(resourceTableId);
        return success;
    }

    @Override
    public boolean updateFunTable(String resourceTableId) {
        boolean success = true;
        String result = checkTableForApply(resourceTableId);
        if (StringUtil.isNotEmpty(result)) {
            throw new PlatformException(result, PlatformExceptionEnum.UNKOWN_ERROR);
        }
        DynaBean resourceTable = metaResourceService.selectOneByPk("JE_CORE_RESOURCETABLE", resourceTableId);
        List<DbModel> dbModels = pcDataService.loadTableColumnBySql(resourceTable.getStr("RESOURCETABLE_TABLECODE"));
        List<String> arraySql = generateUpdateDDL(resourceTableId, dbModels);
//            todo 神通数据-如果存在SY_PARENT外键，就不对此外键进行操作 huxaunhua
        if (JEDatabase.getCurrentDatabase().equalsIgnoreCase(ConstantVars.STR_SHENTONG)
                && metaService.countBySql("select count(*) from user_cons_columns where table_name='" + resourceTable.get("RESOURCETABLE_TABLECODE") + "' and column_name='SY_PARENT'") > 0) {
            arraySql.removeIf(s -> s.contains("foreign key (SY_PARENT)"));
        }
        for (String sql : arraySql) {
            sql = sql.replaceAll("\n", "");
            if (StringUtil.isNotEmpty(sql)) {
                metaService.executeSql(sql);
            }
        }
        afterTableUpdated(resourceTableId);
        return success;
    }


    @Override
    public void syncTreePath(String tableCode, String pkCode, String preFix) {
        metaTableRpcService.syncTreePath(tableCode, pkCode, preFix);
    }

    @Override
    public List<Map<String, Object>> selectSqlTable(JSONArray columnList, JSONArray whereList, JSONArray orderList, String tableCode, String page) {
        StringBuilder sql = new StringBuilder("SELECT ");
        sql.append(getColumnDdl(columnList, tableCode));
        sql.append(" FROM " + tableCode);
        sql.append(getWhereDdl(whereList));
        sql.append(getOrderDdl(orderList));
        if (StringUtil.isNotEmpty(page)) {
            if ("-1".equals(page)) {
                page = "30";
            }
            sql.append(" LIMIT 0," + page);
        }
        List<Map<String, Object>> list = metaService.selectSql(sql.toString());
        return list;
    }

    private StringBuilder getOrderDdl(JSONArray orderList) {
        StringBuilder sql = new StringBuilder("");
        for (int i = 0, size = orderList.size(); i < size; i++) {
            String column = orderList.getString(i);
            if (StringUtil.isEmpty(column)) {
                continue;
            }
            if (i == 0) {
                sql.append(" ORDER BY ");
            }
            sql.append(column);
            if (size - 1 != i) {
                sql.append(",");
            }
        }
        return sql;
    }

    private StringBuilder getWhereDdl(JSONArray whereList) {
        StringBuilder sql = new StringBuilder("");
        for (int i = 0, size = whereList.size(); i < size; i++) {
            String column = whereList.getString(i);
            if (StringUtil.isEmpty(column)) {
                continue;
            }
            if (i == 0) {
                sql.append(" WHERE ");
            }
            sql.append(column);
            if (size - 1 != i) {
                sql.append(" AND ");
            }
        }
        return sql;
    }

    private StringBuilder getColumnDdl(JSONArray columnList, String tableCode) {
        List<DynaBean> columns = metaTableRpcService.selectByColumnCode(tableCode);
        DynaBean dynaBean = new DynaBean(tableCode, true);
       /* String primaryCode = dynaBean.getPkCode();
        for (DynaBean column : columns) {
            if ("ID".equals(column.getStr("TABLECOLUMN_TYPE"))) {
                primaryCode = column.getStr("TABLECOLUMN_CODE");
            }
        }*/
        //boolean containsPrimary = !columnList.contains(primaryCode);
        StringBuilder sql = new StringBuilder("");
        if (columnList.isEmpty()) {
            sql.append(" * ");
            return sql;
        }
        for (int i = 0, size = columnList.size(); i < size; i++) {
            String column = columnList.getString(i);
            if (StringUtil.isEmpty(column)) {
                continue;
            }
            sql.append(column);
            if (size - 1 != i) {
                sql.append(",");
            }
        }
        /*if (containsPrimary) {
            sql.append("," + primaryCode);
        }*/
        return sql;
    }

    @Override
    public List<String> generateInsertSQL(JSONArray columnList, List<Map<String, Object>> list, String tableCode, boolean status) {
        return metaTableRpcService.generateInsertSQL(columnList, list, tableCode, status);
    }

    @Override
    public List<TableDataView> selectParentTable(DynaBean infoById) {
        return metaTableRpcService.selectParentTable(infoById);
    }

    @Override
    public List<TableDataView> selectChildTable(DynaBean infoById) {
        return metaTableRpcService.selectChildTable(infoById);
    }

    @Override
    public List<TableDataView> selectTableByView(DynaBean dynaBean) {
        return metaTableRpcService.selectTableByView(dynaBean);
    }

    @Override
    public List<TableDataView> selectTableByFunc(DynaBean infoById) {
        return metaTableRpcService.selectTableByFunc(infoById);
    }

    @Override
    public List<TableDataView> selectTableByMenus(List<String> list) {
        return metaTableRpcService.selectTableByMenus(list);
    }

    @Override
    public DynaBean doSave(DynaBean dynaBean) {
        return metaTableRpcService.doSave(dynaBean);
    }

    @Override
    public DynaBean pasteTable(String newTableName, String newTableCode, DynaBean dynaBean, String useNewName) {
        return metaTableRpcService.pasteTable(newTableName, newTableCode, dynaBean, useNewName);
    }

    @Override
    public DynaBean doUpdate(DynaBean dynaBean) {
        return metaTableRpcService.doUpdate(dynaBean);
    }

    @Override
    public DynaBean move(String resourceId, String toResourceId, String place) {
        return metaTableRpcService.move(resourceId, toResourceId, place);
    }

    @Override
    public String getTableType(String parentId) {
        return metaTableRpcService.getTableType(parentId);
    }

    @Override
    public DynaBean selectRelation(String pkValue) {
        return metaTableRpcService.selectRelation(pkValue);
    }

    @Override
    public List<Map<String, Object>> loadHistoricalTraces(String resourceId) {
        return metaTableRpcService.loadHistoricalTraces(resourceId);
    }

    @Override
    public void syncTableField(String pkValue, String ckPkValue) {
        metaTableRpcService.syncTableField(pkValue, ckPkValue);
    }

    @Transactional
    @Override
    public String changeTablePrimaryKey(String pkValue, String newCode) throws APIWarnException {

        /**
         * 1.校验、更新元数据
         * 2.获取ddl 并执行
         */
        List<DynaBean> list = metaTableRpcService.findTableNames(Arrays.asList(pkValue.split(",")));
        DynaBean dynaBean = list.get(0);
        List<String> arraySql = new ArrayList<>();
        if (!"VIEW".equals(dynaBean.getStr("RESOURCETABLE_TYPE"))) {
            arraySql = this.generateChangeTablePrimaryKeyDDL(dynaBean.getStr("RESOURCETABLE_TABLECODE"), dynaBean.getStr("RESOURCETABLE_PKCODE"), newCode);
        }
        //校验
        String result = "";
        result = changePrimaryKeyRpcService.checkLocal(dynaBean);
        if (StringUtil.isEmpty(result)) {
            result = changePrimaryKeyRpcService.checkMeta(newCode, dynaBean);
        }
        if (StringUtil.isNotEmpty(result)) {
            return result;
        }
        //执行ddl
        for (String sql : arraySql) {
            try {
                if (StringUtil.isNotEmpty(sql)) {
                    metaService.executeSql(sql);
                }
            } catch (Exception e) {
                String message = e.getMessage();
                if (e.getCause() != null) {
                    message = e.getCause().getMessage();
                }
                throw new PlatformException(MessageUtils.getMessage("table.update.errorInfo", arraySql, message), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR, new Object[]{arraySql}, e);
            }
        }
        //更新元数据
        changePrimaryKeyRpcService.updateMeta(dynaBean, newCode);
        return null;
    }

    @Override
    public DynaBean selectOneByPk(String resourceTable, String resourceId) {
        return metaTableRpcService.selectOneByPk(resourceTable, resourceId);
    }

    @Override
    public void removeTableMetaToMetaNoDDL(String ids) {
        metaTableRpcService.removeTableMetaToMetaNoDDL(ids);
    }

    @Override
    public DynaBean selectOneByCodeToType(String tableCode) {
        return metaTableRpcService.selectOneByCodeToType(tableCode);
    }

    @Override
    public List<DynaBean> selectTableByResourceTablePk(String tableCode, String resourcetableId) {
        return metaTableRpcService.selectTableByResourceTablePk(tableCode, resourcetableId);
    }

    @Override
    public List<DynaBean> selectTableInIds(String tableCode, String tablecolumnId, String[] ids) {
        return metaTableRpcService.selectTableInIds(tableCode, tablecolumnId, ids);
    }

    @Override
    public List<DynaBean> selectColmListInIds(String tablecolumnId) {
        return metaTableRpcService.selectColmListInIds(tablecolumnId);
    }

    @Override
    public Boolean checkTableCodeExcludeCode(DynaBean table) {
        return metaTableRpcService.checkTableCodeExcludeCode(table);
    }

    @Override
    public String getDeleteTableDDlByIds(String ids) {
        return metaTableRpcService.getDeleteTableDDlByIds(ids);
    }

    @Override
    public String checkBeforeDeletion(String ids) {
        return metaTableRpcService.checkBeforeDeletion(ids);
    }

    @Override
    public DynaBean afterImportMetaInfo(DynaBean table, List<Map<String, Object>> lists) {
        return metaTableRpcService.afterImportMetaInfo(table, lists);
    }

    @Override
    public DynaBean beforeImportBuildDynabeanInfo(DynaBean table) {
        return metaTableRpcService.beforeImportBuildDynabeanInfo(table);
    }

    @Override
    public List<DynaBean> selectByColumnCode(String tableCode) {
        return metaTableRpcService.selectByColumnCode(tableCode);
    }

    @Override
    public String checkTableForApply(String tableId) {
        return metaTableRpcService.checkTableForApply(tableId);
    }

}
